import { Injectable } from '@angular/core'
import { Observable, Subject } from 'rxjs'
import { AppStateService } from './app-state.service'
import { JwtHelperService } from '@auth0/angular-jwt'

@Injectable()
export class AppJWTService {
  authHeader = 'Authentication'
  tokenBeaer = 'Bearer'
  tokenKey = 'authToken'
  subject: string

  constructor(private appStateService: AppStateService,
    private jwtHelperService: JwtHelperService) {
      this.updateAuthToken(jwtHelperService.tokenGetter()).subscribe()
  }

  public isAuthenticated(): Observable<Boolean> {
    return Observable.create((ob: Subject<Boolean>) => {
      const token = this.getAuhToken()
      if (!token) {
        ob.next(false)
        return
      }
      ob.next(this.jwtHelperService.isTokenExpired(token) ? false : true)
    })
  }

  public updateAuthToken(authToken: string): Observable<Boolean> {
    return Observable.create((ob: Subject<Boolean>) => {
      if (this.isTokenExpired(authToken))
        ob.error('凭据已失效过期')
      if (authToken.startsWith('Bearer ')) localStorage.setItem(this.tokenKey, authToken.substring(7))
      else localStorage.setItem(this.tokenKey, authToken)
      console.log(this.decodeToken())
      this.subject = this.decodeToken().sub
      ob.next(true)
    })
  }

  /**
  * Decode Sample:
  * {
  "sub": "admin",
  "exp": 1551977200,
  "authorities": [
      "org_mg",
      "pub_mg",
      "self_mg",
      "user_mg"
  ]
  * }
  */
  public getAuthorities(): Observable<Array<any>> {
    return Observable.create((ob: Subject<Array<any>>) => {
      if (this.isTokenExpired())
        ob.error('凭据失效过期')
      const decode = this.decodeToken()
      ob.next(decode.authorities)
    })
  }

  public wipeToken(): void { localStorage.setItem(this.tokenKey, '') }
  public getAuhToken(): string { return this.jwtHelperService.tokenGetter() }
  public decodeToken(): any { return this.jwtHelperService.decodeToken(this.getAuhToken()) }
  public isTokenExpired(token?: string): Boolean { return this.jwtHelperService.isTokenExpired(token ? token : this.getAuhToken()) }
}
